package com.jweb.plugin.c3p0;

import java.beans.PropertyVetoException;
import java.util.Properties;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jweb.plugin.Iplugin;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3p0Plugin implements Iplugin {

	private String jdbcUrl;
	private String user;
	private String password;
	private String driverClass = "com.mysql.jdbc.Driver";
	private int maxPoolSize = 15;//连接池中保留的最大连接数。Default: 15
	private int minPoolSize = 1;
	private int initialPoolSize = 3;//初始化时获取N个连接，取值应在minPoolSize与maxPoolSize之间。Default: 3 
	private int maxIdleTime = 60;//最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0
	private int acquireIncrement = 3;//当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 
	private int checkoutTimeout=15000;//当连接池用完时客户端调用getConnection()后等待获取新连接的时间， 超时后将抛出SQLException,如设为0则无限期等待。单位毫秒 

	private ComboPooledDataSource dataSource;
	private Logger log = LoggerFactory.getLogger(C3p0Plugin.class);

	public C3p0Plugin(String jdbcUrl, String user, String password) {
		this.jdbcUrl = jdbcUrl;
		this.user = user;
		this.password = password;
	}

	public C3p0Plugin(String jdbcUrl, String user, String password, String driverClass) {
		this.jdbcUrl = jdbcUrl;
		this.user = user;
		this.password = password;
		this.driverClass = driverClass != null ? driverClass : this.driverClass;
	}

	public C3p0Plugin(String jdbcUrl, String user, String password, String driverClass, Integer maxPoolSize, Integer minPoolSize, Integer initialPoolSize, Integer maxIdleTime, Integer acquireIncrement) {
		initC3p0Properties(jdbcUrl, user, password, driverClass, maxPoolSize, minPoolSize, initialPoolSize, maxIdleTime, acquireIncrement);
	}

	private void initC3p0Properties(String jdbcUrl, String user, String password, String driverClass, Integer maxPoolSize, Integer minPoolSize, Integer initialPoolSize, Integer maxIdleTime,
			Integer acquireIncrement) {
		this.jdbcUrl = jdbcUrl;
		this.user = user;
		this.password = password;
		this.driverClass = driverClass != null ? driverClass : this.driverClass;
		this.maxPoolSize = maxPoolSize != null ? maxPoolSize : this.maxPoolSize;
		this.minPoolSize = minPoolSize != null ? minPoolSize : this.minPoolSize;
		this.initialPoolSize = initialPoolSize != null ? initialPoolSize : this.initialPoolSize;
		this.maxIdleTime = maxIdleTime != null ? maxIdleTime : this.maxIdleTime;
		this.acquireIncrement = acquireIncrement != null ? acquireIncrement : this.acquireIncrement;
	}

	public C3p0Plugin(Properties properties) {
		Properties ps = properties;
		initC3p0Properties(ps.getProperty("jdbc.url"), ps.getProperty("jdbc.username"), ps.getProperty("jdbc.password"), ps.getProperty("jdbc.driverClass"), toInt(ps.getProperty("maxPoolSize")),
				toInt(ps.getProperty("minPoolSize")), toInt(ps.getProperty("initialPoolSize")), toInt(ps.getProperty("maxIdleTime")), toInt(ps.getProperty("acquireIncrement")));
	}

	public boolean start() {
		dataSource = new ComboPooledDataSource();
		dataSource.setJdbcUrl(jdbcUrl);
		dataSource.setUser(user);
		dataSource.setPassword(password);
		try {
			dataSource.setDriverClass(driverClass);
		} catch (PropertyVetoException e) {
			dataSource = null;
			System.err.println("C3p0Plugin start error");
			throw new RuntimeException(e);
		}
		dataSource.setMaxPoolSize(maxPoolSize);
		dataSource.setMinPoolSize(minPoolSize);
		dataSource.setInitialPoolSize(initialPoolSize);
		dataSource.setMaxIdleTime(maxIdleTime);
		dataSource.setAcquireIncrement(acquireIncrement);
		dataSource.setCheckoutTimeout(checkoutTimeout);
		log.info("[Plugin]==>C3P0加载完成！");
		//顺带加载JdbcTmplate=================================================
//		try {
//			JWebFilter.setJdbctemplate(new JdbcTemplate(getDataSource()));
//			JWebFilter.getJdbctemplate().query("SELECT 1", null);
//		} catch (Exception e) {
//			log.error("[Plugin]==>C3P0数据库连接失败");
//		}
		return true;
	}

	private Integer toInt(String str) {
		return Integer.parseInt(str);
	}

	public DataSource getDataSource() {
		return dataSource;
	}

	public boolean stop() {
		log.warn("==>关闭：C3P0");
		if (dataSource != null)
			dataSource.close();
		return true;
	}
}
